package com.such.kit.message.bean;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import com.such.kit.Logger;
import com.such.kit.validate.ValidateCommons;

/**
 * @author SUCH
 * <pre>
 * 信使
 * 
 * 一般来说，一个 {@link MessageItem 消息项} 传输一条数据处理时产生的消息
 * 信使则对多个 {@link MessageItem 消息项} 进行统一管理
 * </pre>
 */
public class Messager<T> {

	public static final String STATUS_ERROR = "ERROR";
	public static final String STATUS_WARN = "WARN";
	public static final String STATUS_SUCCESS = "SUCCESS";

	/** maxRecordSize：最大（MessagerItem）记录数，超过此值则不再记录，默认为 0（不限制） */
	private int maxRecordSize = 0;
	/** itemsResult：MessagerItem 存储 */
	private Map<String, MessageItem<T>> itemsResult = new HashMap<String, MessageItem<T>>();
	/** itemKeys：MessagerItem key 存储 */
	private List<String> itemKeys = new ArrayList<String>();
	/** itemStatusResult：按状态分组 MessagerItem key 存储 */
	private Map<String, List<String>> itemStatusResult = new HashMap<String, List<String>>();
	/** itemStatusAccounting：按状态分组统计 */
	private Map<String, Integer> itemStatusAccounting = new HashMap<String, Integer>();
	/** status：最终状态码 */
	private String status;
	/** statusDescr：最终状态码描述 */
	private String statusDescr;

	public Messager() {
	}

	public Messager(int maxRecordSize) {
		this.maxRecordSize = maxRecordSize;
	}

	public int getMaxRecordSize() {
		return this.maxRecordSize;
	}

	public void setMaxRecordSize(int maxRecordSize) {
		this.maxRecordSize = maxRecordSize;
	}

	public void addItem(MessageItem<T> item) {
		if (ValidateCommons.isNotEmpty(item)) {
			if (this.maxRecordSize > 0 && this.itemsResult.size() >= this.maxRecordSize) {
				Logger.info(getClass(), "MessagerItem 超出设定的最大记录数");
			} else {
				String itemKey = item.getKey();
				String status = item.getStatus();
				this.itemsResult.put(itemKey, item);
				this.itemKeys.add(itemKey);
				List<String> statusItemKeys = this.itemStatusResult.get(status);
				if (ValidateCommons.isEmpty(statusItemKeys)) {
					statusItemKeys = new ArrayList<String>();
				}
				statusItemKeys.add(itemKey);
				this.itemStatusResult.put(status, statusItemKeys);
				Integer statusCount = this.itemStatusAccounting.get(status);
				if (ValidateCommons.isEmpty(statusCount, false)) {
					statusCount = 0;
				}
				statusCount++;
				this.itemStatusAccounting.put(status, statusCount);
			}
		}
	}

	public void addItems(List<MessageItem<T>> items) {
		if (ValidateCommons.isNotEmpty(items)) {
			for (MessageItem<T> item : items) {
				addItem(item);
			}
		}
	}

	public Map<String, MessageItem<T>> getItemsResult() {
		return this.itemsResult;
	}

	public List<String> getItemKeys() {
		return this.itemKeys;
	}

	public Map<String, List<String>> getItemStatusResult() {
		return this.itemStatusResult;
	}

	public MessageItem<T> getItem(String itemKey) {
		return this.itemsResult.get(itemKey);
	}

	public List<MessageItem<T>> getItems() {
		List<MessageItem<T>> items = new ArrayList<MessageItem<T>>();
		if (ValidateCommons.isNotEmpty(this.itemKeys)) {
			for (String itemKey : this.itemKeys) {
				items.add(this.itemsResult.get(itemKey));
			}
		}
		return items;
	}

	public List<MessageItem<T>> getItems(String itemStatus) {
		List<MessageItem<T>> items = new ArrayList<MessageItem<T>>();
		if (ValidateCommons.isNotEmpty(this.itemStatusResult)) {
			List<String> itemKeys = this.itemStatusResult.get(itemStatus);
			if (ValidateCommons.isNotEmpty(itemKeys)) {
				for (String itemKey : itemKeys) {
					items.add(this.itemsResult.get(itemKey));
				}
			}
		}
		return items;
	}

	public Map<String, Integer> getItemStatusAccounting() {
		return this.itemStatusAccounting;
	}

	public int getItemStatusCount(String itemStatus) {
		Integer count = this.itemStatusAccounting.get(itemStatus);
		if (ValidateCommons.isEmpty(count, false)) {
			return 0;
		}
		return count;
	}

	public String getStatus() {
		return this.status;
	}

	public void setStatus(String status) {
		this.status = status;
	}

	public String getStatusDescr() {
		return this.statusDescr;
	}

	public void setStatusDescr(String statusDescr) {
		this.statusDescr = statusDescr;
	}

	/**
	 * <p>方法名：isSuccessByStatus</p>
	 * <p>描述：检查 status 是否在 checkStatuses 中，满足条件则为 true</p>
	 * @param checkStatuses 状态检查列表
	 * @return boolean true 为成功
	 */
	public boolean isSuccessByStatus(String... checkStatuses) {
		if (ValidateCommons.isNotEmpty(checkStatuses)) {
			Set<String> checker = new HashSet<String>(Arrays.stream(checkStatuses).collect(Collectors.toList()));
			if (checker.contains(status)) {
				return false;
			}
			return true;
		}
		return false;
	}

	/**
	 * <p>方法名：isSuccessByCount</p>
	 * <p>描述：检查 MessagerItem.status 是否在 checkStatuses 中且 count 大于 0，满足条件则为 true</p>
	 * @param checkStatuses 状态检查列表
	 * @return boolean true 为成功
	 */
	public boolean isSuccessByCount(String... checkStatuses) {
		if (ValidateCommons.isNotEmpty(checkStatuses)) {
			for (String checkStatus : checkStatuses) {
				if (getItemStatusCount(checkStatus) > 0) {
					return false;
				}
			}
			return true;
		}
		return false;
	}

}
